import config from '@/static/config.js';

const utils = {
    /**
     * @description 显示错误消息，方便开发人员查找错误消息
     * @param {string} msg 错误信息
     * @param {array} otherArgs 调用方法参数
     */
    warn: function (msg, otherArgs) {
        !utils.isUndefined(console) && console.error(msg, otherArgs)
    },
    /**
     * @description 判定是否普通对象
     * @param {any} obj 
     * @return {boolean}
     */
    isPlainObject: function (obj) {
        return obj && typeof obj === 'object' && Object.getPrototypeOf(obj) === Object.prototype || false
    },
    /**
     * @description 判定是否数组
     * @param {any} obj
     * @return {boolean}
     */
    isArray: function (obj) {
        return Object.prototype.toString.call(obj) === '[object Array]';
    },
    /**
     * @description 判定是否函数
     * @param {any} obj
     * @return {boolean}
     */
     isFunction: function (obj) {
        return Object.prototype.toString.call(obj) === '[object Function]';
    },
    /**
     * @description 判定是日期类型
     * @param {any} obj
     * @return {boolean}
     */
     isDate: function (obj) {
        return Object.prototype.toString.call(obj) === '[object Date]';
    },
    /**
     * @description 判定是否数字类型
     * @param {any} obj
     * @return {boolean}
     */
     isNumber: function (obj) {
        return Object.prototype.toString.call(obj) === '[object Number]';
    },
    /**
     * @description 判断是否字符串
     * @param {any} obj
     * @return {boolean}
     */
     isString: function (obj) {
        return Object.prototype.toString.call(obj) === '[object String]';
    },
    /**
     * @description 判断是否boolean类型
     * @param {any} obj
     * @return {boolean}
     */
     isBoolean: function (obj) {
        return Object.prototype.toString.call(obj) === '[object Boolean]';
    },
    /**
     * @description 判定是否Null值
     * @param {any} obj
     * @return {boolean}
     */
     isNull: function (obj) {
        return Object.prototype.toString.call(obj) === '[object Null]';
    },
    /**
     * @description 判定是否undefined
     * @param {any} obj
     * @return {boolean}
     */
    isUndefined: function (obj) {
        return Object.prototype.toString.call(obj) === '[object Undefined]';
    },
    /**
     * @description 判定是否null或者undefined值
     * @param {any} obj
     * @return {boolean}
     */
    isNullOrUndefined: function (obj) {
        return utils.isNull(obj) || utils.isUndefined(obj)
    },
    /**
     * @description 判定是否数值型数据，包含字符串数据
     * @param {any} obj
     * @return {boolean}
     */
    isNumeric: function (obj) {
        return obj - parseFloat(obj) >= 0
    },
    /**
     * 判定是否整数
     * @method isInt
     * @param {any} obj
     * @return {boolean}
     */
    isInt: function (obj) {
        return utils.isNumeric(obj) && (String(obj).indexOf('.') === -1)
    },
    /**
     * @description 判定是否为空值（null/undefined/''/NaN）
     * @param {any} obj
     * @return {boolean}
     */
    isEmpty: function (obj) {
        return utils.isNull(obj) || utils.isUndefined(obj) || utils.isString(obj) && obj === '' || Object.is(NaN, obj)
    },
    /**
     * @description 将obj属性并入target对象中，默认深拷贝，当参数target、参数obj无效时返回target
     * @param {object} target 目标对象
     * @param {object} obj
     * @param {boolean} isCover 是否拷贝（false：以target字段为准）
     * @param {boolean} isDepth 是否深拷贝（false：不做递归，完全覆盖）
     * @return {object} target
     */
     assign: function (target, obj, isCover = true, isDepth = true) {
        if (!utils.isPlainObject(target) || !utils.isPlainObject(obj)) {
            utils.warn('调用utils.assign() target或者obj参数不是普通对象', target, obj)
            return target
        }

        isCover = !!isCover
        isDepth = !!isDepth

        let props = Object.keys(obj)
        for (let i = 0, len = props.length; i < len; i++) {
            if (target.hasOwnProperty(props[i]) && !isCover) {
                continue
            }

            if (isDepth && utils.isPlainObject(obj[props[i]])) {
                target[props[i]] = {}
                utils.assign(target[props[i]], obj[props[i]], isCover, isDepth)
            } else {
                target[props[i]] = obj[props[i]]
            }
        }

        return target
    },
    /**
     * @description 判定是否带协议
     * @param {string} url 跳转地址
     */
    isSiteUrl (url) {
        if (url && (url.indexOf('http://') === 0 || url.indexOf('https://') === 0)) {
            return true
        }
        return false
    },
    /**
     * @description 判定是否带二级根目录
     * @param {string} url 跳转地址
     */
    parseAppUrl (url) {
        let appDir = config.appDir ? `/${config.appDir}` : '';
        return (utils.isSiteUrl(url) ? '' : appDir) + url;
    },
    /**
     * @description 站点内页面跳转
     * @param {string} url 跳转地址，仍然是以'/'开头的地址
     */
     innerRedirect (url) {
        window.location.href = utils.parseAppUrl(url)
    },
    /**
     * @description 站点内跳转地址，不留历史记录
     * @param {string} url 当前替换地址
     */
    innerReplace (url) {
        window.location.replace(utils.parseAppUrl(url))
    },
    /**
     * @description 弹出运用内页面
     * @param {string} url 打开页面url
     * @returns {Window} 返回子页面的window对象
     */
    innerOpen (url) {
        return window.open(utils.parseAppUrl(url))
    },
        // 本地存储
    localStorage: {
        /**
         * @description localStorage.set
         * @param {string} key 
         * @param {string|object} value 
         * @return {boolean} 表示是否设置成功
         */
        set: function (key, value) {
            if (!utils.isString(key) || key === '' || utils.isNullOrUndefined(value)) {
                utils.warn('utils.localStorage.set 参数key不能为空或者value不能为undefined/null')
                return false
            }
            if (typeof value === 'object') {
                value = JSON.stringify(value)
            }

            window.localStorage.setItem(key, value)
            return true
        },
        /**
         * @description localStorage.get
         * @param {string} key
         * @param {any} default
         * @return {string|null}
         */
        get: function (key, defaultValue) {
            defaultValue = arguments.length === 2 ? defaultValue : null
            if (!utils.isString(key) || key === '') {
                arguments.length < 2 && utils.warn('utils.localStorage.get 参数key必须为字符串，且不能为空')
                return defaultValue
            }
            const val = window.localStorage.getItem(key)
            if (utils.isNull(val)) {
                return defaultValue
            } else {
                return val
            }
        },
        /**
         * @description localStorage.remove
         * @param {string} key
         * @return {boolean} 是否删除成功
         */
        remove: function (key) {
            if (!utils.isString(key) || key === '') {
                utils.warn('utils.localStorage.remove 参数key不能为空')
                return false
            }
            window.localStorage.removeItem(key)
            return true
        },
        /**
         * @description localStorage.clear
         */
        clear: function () {
            window.localStorage.clear()
        }
    },
    // 本地存储
    sessionStorage: {
        /**
         * @description sessionStorage.set
         * @param {string} key
         * @param {string|object} value
         * @return {boolean} 表示是否设置成功
         */
        set: function (key, value) {
            if (!utils.isString(key) || key === '' || utils.isNullOrUndefined(value)) {
                utils.warn('utils.sessionStorage.set 参数key不能为空或者value不能为undefined/null')
                return false
            }
            if (typeof value === 'object') {
                value = JSON.stringify(value)
            }

            window.sessionStorage.setItem(key, value)
            return true
        },
        /**
         * @description sessionStorage.get
         * @param {string} key
         * @param {any} default
         * @return {string|null}
         */
        get: function (key, defaultValue) {
            defaultValue = arguments.length === 2 ? defaultValue : null
            if (!utils.isString(key) || key === '') {
                arguments.length < 2 && utils.warn('utils.sessionStorage.get 参数key必须为字符串，且不能为空')
                return defaultValue
            }
            const val = window.sessionStorage.getItem(key)
            if (utils.isNull(val)) {
                return defaultValue
            } else {
                return val
            }
        },
        /**
         * @description sessionStorage.remove
         * @param {string} key
         * @return {boolean} 是否删除成功
         */
        remove: function (key) {
            if (!utils.isString(key) || key === '') {
                utils.warn('utils.sessionStorage.remove 参数key不能为空')
                return false
            }
            window.sessionStorage.removeItem(key)
            return true
        },
        /**
         * @description sessionStorage.clear
         */
        clear: function () {
            window.sessionStorage.clear()
        }
    },
    // cookie操作
    cookie: {
        /**
         * @description cookie.set
         * @param {string} key
         * @param {string|value} value
         * @param {number} expiredays 过期时间
         * @return {boolean} 表示是否设置成功
         */
        set: function (key, value, expiredays) {
            var date
            if (!utils.isString(key) || key === '' || utils.isNullOrUndefined(value)) {
                utils.warn('utils.cookie.set 参数key不能为空或者value不能为undefined/null')
                return false
            }
            if (utils.isInt(expiredays)) {
                date = new Date()
                date.setDate(date.getDate() + expiredays)
            }

            document.cookie = key + '=' + encodeURIComponent(value) + (!date ? '' : ';expires=' + date.toGMTString()) +
                (config.useCookieMainDomain ? ';domain=' + utils.getDomain() : '') + ';path=/;SameSite=' + config.cookieSameSite
            return true
        },
        /**
         * @description cookie.get
         * @param {string} key
         * @return {string|null}
         */
        get: function (key, defaultValue) {
            defaultValue = arguments.length === 2 ? defaultValue : null
            if (!utils.isString(key) || key === '') {
                utils.warn('utils.cookie.get 参数key不能为空')
                return defaultValue
            }

            var arr = document.cookie.match(new RegExp('(^| )' + key + '=([^;]*)(;|$)'))

            if (utils.isArray(arr)) {
                return decodeURIComponent(arr[2])
            }

            return defaultValue
        },
        /**
         * @description cookie.remove
         * @param {string} key
         * @return {boolean} 返回是移除成功
         */
        remove: function (key) {
            return utils.cookie.set(key, '', -1000)
        }
    },
    getDomain (hostname) {
        var host = hostname || location.hostname
        var ip = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
        if (ip.test(host) === true || host === 'localhost') {
            return host
        }
        var regex = /([^]*).*/
        var match = host.match(regex)

        if (match) {
            host = match[1]
        }

        if (host) {
            var strAry = host.split('.')
            if (strAry.length > 1) {
                host = strAry[strAry.length - 2] + '.' + strAry[strAry.length - 1]
            }
        }
        return '.' + host
    },
    // 本地存储
    localStorage: {
        /**
         * @description localStorage.set
         * @param {string} key 
         * @param {string|object} value 
         * @return {boolean} 表示是否设置成功
         */
        set: function (key, value) {
            if (!utils.isString(key) || key === '' || utils.isNullOrUndefined(value)) {
                utils.warn('utils.localStorage.set 参数key不能为空或者value不能为undefined/null')
                return false
            }
            if (typeof value === 'object') {
                value = JSON.stringify(value)
            }

            window.localStorage.setItem(key, value)
            return true
        },
        /**
         * @description localStorage.get
         * @param {string} key
         * @param {any} default
         * @return {string|null}
         */
        get: function (key, defaultValue) {
            defaultValue = arguments.length === 2 ? defaultValue : null
            if (!utils.isString(key) || key === '') {
                arguments.length < 2 && utils.warn('utils.localStorage.get 参数key必须为字符串，且不能为空')
                return defaultValue
            }
            const val = window.localStorage.getItem(key)
            if (utils.isNull(val)) {
                return defaultValue
            } else {
                return val
            }
        },
        /**
         * @description localStorage.remove
         * @param {string} key
         * @return {boolean} 是否删除成功
         */
        remove: function (key) {
            if (!utils.isString(key) || key === '') {
                utils.warn('utils.localStorage.remove 参数key不能为空')
                return false
            }
            window.localStorage.removeItem(key)
            return true
        },
        /**
         * @description localStorage.clear
         */
        clear: function () {
            window.localStorage.clear()
        }
    },
    // 本地存储
    sessionStorage: {
        /**
         * @description sessionStorage.set
         * @param {string} key
         * @param {string|object} value
         * @return {boolean} 表示是否设置成功
         */
        set: function (key, value) {
            if (!utils.isString(key) || key === '' || utils.isNullOrUndefined(value)) {
                utils.warn('utils.sessionStorage.set 参数key不能为空或者value不能为undefined/null')
                return false
            }
            if (typeof value === 'object') {
                value = JSON.stringify(value)
            }

            window.sessionStorage.setItem(key, value)
            return true
        },
        /**
         * @description sessionStorage.get
         * @param {string} key
         * @param {any} default
         * @return {string|null}
         */
        get: function (key, defaultValue) {
            defaultValue = arguments.length === 2 ? defaultValue : null
            if (!utils.isString(key) || key === '') {
                arguments.length < 2 && utils.warn('utils.sessionStorage.get 参数key必须为字符串，且不能为空')
                return defaultValue
            }
            const val = window.sessionStorage.getItem(key)
            if (utils.isNull(val)) {
                return defaultValue
            } else {
                return val
            }
        },
        /**
         * @description sessionStorage.remove
         * @param {string} key
         * @return {boolean} 是否删除成功
         */
        remove: function (key) {
            if (!utils.isString(key) || key === '') {
                utils.warn('utils.sessionStorage.remove 参数key不能为空')
                return false
            }
            window.sessionStorage.removeItem(key)
            return true
        },
        /**
         * @description sessionStorage.clear
         */
        clear: function () {
            window.sessionStorage.clear()
        }
    },
    // cookie操作
    cookie: {
        /**
         * @description cookie.set
         * @param {string} key
         * @param {string|value} value
         * @param {number} expiredays 过期时间
         * @return {boolean} 表示是否设置成功
         */
        set: function (key, value, expiredays) {
            var date
            if (!utils.isString(key) || key === '' || utils.isNullOrUndefined(value)) {
                utils.warn('utils.cookie.set 参数key不能为空或者value不能为undefined/null')
                return false
            }
            if (utils.isInt(expiredays)) {
                date = new Date()
                date.setDate(date.getDate() + expiredays)
            }

            document.cookie = key + '=' + encodeURIComponent(value) + (!date ? '' : ';expires=' + date.toGMTString()) +
                (config.useCookieMainDomain ? ';domain=' + utils.getDomain() : '') + ';path=/;SameSite=' + config.cookieSameSite
            return true
        },
        /**
         * @description cookie.get
         * @param {string} key
         * @return {string|null}
         */
        get: function (key, defaultValue) {
            defaultValue = arguments.length === 2 ? defaultValue : null
            if (!utils.isString(key) || key === '') {
                utils.warn('utils.cookie.get 参数key不能为空')
                return defaultValue
            }

            var arr = document.cookie.match(new RegExp('(^| )' + key + '=([^;]*)(;|$)'))

            if (utils.isArray(arr)) {
                return decodeURIComponent(arr[2])
            }

            return defaultValue
        },
        /**
         * @description cookie.remove
         * @param {string} key
         * @return {boolean} 返回是移除成功
         */
        remove: function (key) {
            return utils.cookie.set(key, '', -1000)
        }
    },
    getDomain (hostname) {
        var host = hostname || location.hostname
        var ip = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
        if (ip.test(host) === true || host === 'localhost') {
            return host
        }
        var regex = /([^]*).*/
        var match = host.match(regex)

        if (match) {
            host = match[1]
        }

        if (host) {
            var strAry = host.split('.')
            if (strAry.length > 1) {
                host = strAry[strAry.length - 2] + '.' + strAry[strAry.length - 1]
            }
        }
        return '.' + host
    }
}

export default utils;